const formidable = require("formidable");
const express = require('express');
const path = require('path');
const fs = require('fs');
const router = express.Router();

/**
 * @param dirPath
 * @param renameObj
 * 合并切片分片函数，使用readFileSync将文件分片读取为buffer类型，
 * 使用Buffer.concat()将buffer数组拼接成buffer文件并进行重命名
 */
const combineFile = (dirPath, renameObj) => {
    return new Promise((reslove, reject) => {
        let files = fs.readdirSync(dirPath);
        let currentFilds = files.filter(file => {
            let stats = fs.statSync(path.join(dirPath, file));
            return stats.isFile() && file.startsWith(renameObj.name)
        }).sort((f1, f2) => {
            return f1.slice(-2, -1) - f2.slice(-2, -1);
        });
        let buffers = [];
        currentFilds.forEach(currFile => {
            let buffer = fs.readFileSync(path.join(dirPath, currFile));
            buffers.push(buffer);
        });
        let appendPath = path.join(dirPath, renameObj.filename);
        let concatBuffer = Buffer.concat(buffers);
        fs.writeFileSync(appendPath, concatBuffer);

        currentFilds.forEach((currentFild, index) => {
            fs.unlinkSync(path.join(dirPath, currentFild));
        });
        reslove();
    })
};

/**
 * @param oldPath
 * @param name
 * 使用md5与index对配一个上传成功的分片进行重新命名
 */
const pieceRename = (oldPath, name) => {
    return new Promise((resolve, reject) => {
        let newPath = path.join(path.dirname(oldPath), name)
        fs.rename(oldPath, newPath, (err) => {
            if (err) {
                reject(err);
                console.log(`${oldPath}, 重命名失败`);
            };
            resolve();
            console.log(`${oldPath}, 重命名完成, ${newPath}`);

        });
    })
}

/**
 * @param req
 * @param res
 * @param next
 * 处理前端上传的文件分片
 */
const uploadFile = (req, res, next) => {
    const form = new formidable.IncomingForm();
    form.encoding = 'utf-8';
    form.maxFileSize = 1024 * 1024 * 300;
    form.uploadDir = path.join(process.cwd(), 'uploads');
    form.keepExtensions = true;
    form.parse(req, async (err, fields, files) => {
        if (err) return next(err);
        let {file: {path = ''}} = files;
        await pieceRename(path, fields.name, res);

        return res.json({
            code: 0,
            msg: '上传成功',
            data: {}
        })
    });
};


const testApi = (req, res, next) => {
    const data = req.body;
    res.json({
        code: 0,
        msg: '测试成功',
        data: data
    })
};

const mkFile = async (req, res, next) => {
    const combinePath = path.join(process.cwd(), 'uploads');
    await combineFile(combinePath, req.body);
    return res.json({
        code: 0,
        msg: '请求成功',
        data: {}
    })
};

router.post('/upload', uploadFile)
    .post('/test/api', testApi)
    .post('/mkfile', mkFile);

module.exports = router;